CORS设置跨域不生效排查之路 |
您所在的位置:网站首页 › beego web 过滤器不生效 › CORS设置跨域不生效排查之路 |
结构:springboot2.x版本 CORS(跨域资源共享),可以把其当做是通过设置http响应头来允许不同协议、ip、port可以跨域请求。 在springboot中,一般常采用两种方式实现CORS: 一,通过拦截器的方式,通过继承WebMvcConfigurationSupport,重写addCorsMappings方法,具体代码如下: @Override protected void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") .allowCredentials(true) .allowedHeaders("*") .allowedMethods("*") .allowedOrigins("*"); super.addCorsMappings(registry); } 二,通过过滤器的方式,具体代码如下: @Configuration public class GlobalCorsConfig { @Bean public CorsFilter corsFilter() { CorsConfiguration config = new CorsConfiguration(); //开放哪些ip、端口、域名的访问权限,星号表示开放所有域 config.addAllowedOrigin("*"); //是否允许发送Cookie信息 config.setAllowCredentials(true); //开放哪些Http方法,允许跨域访问 config.addAllowedMethod("GET","POST", "PUT", "DELETE"); //允许HTTP请求中的携带哪些Header信息 config.addAllowedHeader("*"); //添加映射路径,“/**”表示对所有的路径实行全局跨域访问权限的设置 UrlBasedCorsConfigurationSource configSource = new UrlBasedCorsConfigurationSource(); configSource.registerCorsConfiguration("/**", config); return new CorsFilter(configSource); } } 接下来,我们对上述两种方式,存在失效情况分别描述: 方式1,可能失效的情况如下: 第一: 如果一个项目中存在多个WebMvcConfigurationSupport或者WebMvcConfigurerAdapter,可能会导致设置的允许跨域addCorsMappings不生效。 第二:如果一个项目中存在多个自定义的拦截器,执行顺序导致设置跨域失效,伪代码如下: 如上,执行顺序是从上至下的,导致业务拦截器先执行,本应该跨域拦截器在业务拦截器前执行。
方式2,使用过滤器的方式,我们应该知道过滤器是先与拦截器执行的。所以,这是我们就不要考虑到和拦截器冲突问题。其实,我项目中采用的就是这种方式,过滤器设置CORS允许跨域请求,拦截器处理业务代码(问题出现在拦截器中)。 出现CORS设置不生效时,程序的结构是,存在GlobalCorsConfig的设置就是方式二的设置,然后就是一个业务的拦截器,伪代码如下: 拦截器中代码也很简单,就是验证请求中的key是否合法,合法则不拦截,不合法拦截并响应,代码如下: 也就是采用response流输出的时候,调用了reset()函数,还记得最开头的时候,CORS设置可以简单的理解为对response设置请求头,或者你也会看到另外一种写法,如下:(也是对CORS设置的一种方式) HttpServletResponse response = (HttpServletResponse) res; String allowedOriginsUrl = configurationUtil.getAllowedOriginsUrl(); String[] allowedOriginsUrlArr = allowedOriginsUrl.split(","); for(String temp : allowedOriginsUrlArr){ response.setHeader("Access-Control-Allow-Origin",temp); // 允许的来源 } response.setHeader("Access-Control-Allow-Credentials", "true"); // 是否允许证书 response.setHeader("Access-Control-Allow-Methods", "*"); // 允许的请求方式 response.setHeader("Access-Control-Max-Age", "3600"); // 预检请求的有效期 response.setHeader("Access-Control-Allow-Headers", "*"); chain.doFilter(req, res); 由此,可以更清楚的看出,其实就是response设置了头部header,来实现允许跨域请求。那上面的问题就很明显了,到过滤器的时候,设置了response的响应头允许跨域,但到了拦截器的时候,又把reponse重置了,导致设置的不生效。
结论: 1.采用CORS方式,设置允许跨域时,推荐filter的方式,这种方式先于拦截器执行。 2.如果遇到不生效的情况下,我们先采用一种最简单的方式来设置允许跨域,如果可行,放在你项目中不能使用,需要排查是否存在冲突问题了 3.解决跨域还有其他的多种方案(推荐采用代理nginx、网关方式)
|
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |